package org.example.ShejiModel.Proxy.DTProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 *
 获取代理对象的工厂类
 代理类也实现了对应的接口
 */
public class ProxyFactory {

    //声明目标对象
    private  TrainStation trainStation = new TrainStation();

    public SellTickets getProxyObject(){
    //返回代理对象
        SellTickets proxyObject = (SellTickets) Proxy.newProxyInstance(trainStation.getClass().getClassLoader(),
                trainStation.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * Object proxy :代理对象,和proxyObject是同一个对象，在invoke中基本不用
                     * Method method : 对接口中的方法 (sell()方法) 进行封装的method对象
                     * Object[] args : 调用方法 (sell()方法) 的实际参数, 本例中sell()方法无参数
                     *
                     *返回值 就是sell()方法的返回值 ,由于sell()方法没有返回值 因此就是返回null
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //代理对象对目标对象进行增强
                        /**
                         *执行目标对象的方法 method就表示sell()方法
                         * 通过反射调用method对象中的invoke方法
                         * 参数表示 : trainStation要调用的sell方法所属类的实例对象 ,args发放的参数
                         */
                        Object obj = method.invoke(trainStation, args);
                        System.out.println("invoke方法执行了");
                        /**  为什么debug执行结果是这样？  invoke方法调用了多次
                         invoke方法执行了
                         买票成功.....
                         invoke方法执行了
                         invoke方法执行了
                        */
                        return obj;
                   }
                }
        );
        /**
         * newProxyInstance方法中的三个参数
         * ClassLoader loader : 类加载器，用于加载代理类，可以通过目标对象获得类加载器
         *  Class<?>[] interfaces : 代理类实现的接口的字节码对象
         *InvocationHandler h  :代理对象的调用处理程序
         */
        return  proxyObject;
    }
}
